package com.coldtech.circlecrash.units;

import java.awt.Color;
import java.awt.geom.Point2D;

import com.coldtech.circlecrash.Applet;
import com.coldtech.circlecrash.Player;
import com.coldtech.circlecrash.Square;
import com.coldtech.circlecrash.handler.UnitHandler;

public class Unit {
	public static int MAX_SIZE = 50;
	public static int MIN_SIZE = 5;

	private Point2D.Double pos = null;
	private double size, newsize, resizespeed;
	private boolean resize;

	private Point2D.Double move = null;
	private Point2D.Double vel = null;
	private boolean isMoving;
	private boolean isMovingTo;

	private Square square = null;
	private UnitHandler unitHandler = null;
	private Color color = Color.RED;
	private int actionDelay;

	private Player player = null;

	private boolean isMother = false;
	private boolean isSelected = false;
	private boolean isControlable = false;

	public Unit(UnitHandler unitHandler, Player player, int x, int y) {
		this.unitHandler = unitHandler;
		this.pos = new Point2D.Double(x, y);
		this.vel = new Point2D.Double(0, 0);
		this.move = new Point2D.Double(0, 0);
		this.isMoving = false;
		this.isMovingTo = false;

		this.player = player;

		this.newsize = 0.0F;
		this.size = 0.0F;
		this.resize = false;

		this.actionDelay = 0;
		this.isSelected = false;
		unitHandler.addUnit(this);
	}

	public void update() {
		if (this.resize) {
			if (this.size < this.newsize - 0.1
					|| this.size > this.newsize + 0.1) {
				System.out.println("Resize " + (this.size));
				setSize(this.size
						+ ((this.newsize - this.size) / this.resizespeed));
			} else {
				setSize(this.newsize);
				this.resize = false;
			}
		}
		if (this.actionDelay >= 60) {
			action();
			this.actionDelay = 0;
		} else {
			this.actionDelay++;
		}
	}

	public void move() {
		if (this.isMovingTo) {
			double distance = this.move.distance(this.pos);
			if (distance >= 1D || distance <= -1D) {
				double speed = 2.0;
				System.out.println("X: "
						+ ((this.move.getX() - this.pos.getX()) / distance));
				double newVelX = ((this.move.getX() - this.pos.getX()) / distance)
						* speed;
				double newVelY = ((this.move.getY() - this.pos.getY()) / distance)
						* speed;
				addVelocity(newVelX, newVelY);
				this.isMoving = true;
			} else {
				this.isMovingTo = false;
			}
		}
		if (this.isMoving) {
			setVelocity(this.vel.getX() * 0.5, this.vel.getY() * 0.5);
			double velo = this.vel.distanceSq(0, 0);
			
			if(velo >= 2.0D) {
				this.vel.setLocation(velo * (this.vel.getX() / velo), velo * (this.vel.getY() / velo));
			}
			
			double newPosX = this.pos.getX() + this.vel.getX();
			double newPosY = this.pos.getY() + this.vel.getY();
			if (!this.isMother) {
				if (newPosX < this.size / 2)
					newPosX = this.size / 2;
				if (newPosY < this.size / 2)
					newPosY = this.size / 2;

				if (newPosX >= Applet.size.getWidth() - (this.size / 2) - 1)
					newPosX = Applet.size.getWidth() - (this.size / 2) - 1;
				if (newPosY >= Applet.size.getHeight() - (this.size / 2) - 1)
					newPosY = Applet.size.getHeight() - (this.size / 2) - 1;
			} else {
				if (newPosX < 0.0)
					newPosX = 0.0;
				if (newPosY < 0.0)
					newPosY = 0.0;

				if (newPosX >= Applet.size.getWidth() - 1)
					newPosX = Applet.size.getWidth() - 1;
				if (newPosY >= Applet.size.getHeight() - 1)
					newPosY = Applet.size.getHeight() - 1;
			}
			this.pos.setLocation(newPosX, newPosY);

			if (this.square != null) {
				if (!this.square.isInSquare(this)) {
					unitHandler.getSquareField().findNewSquare(this);
				}
			} else {
				unitHandler.getSquareField().findSquare(this);
			}

			if (isMother) {
				setVelocity(this.move.getX() - this.pos.getX(),
						this.move.getY() - this.pos.getY());
			}

			if (this.vel.distanceSq(0, 0) <= 0.1D) {
				setVelocity(0, 0);
				this.isMoving = false;
			}
		}

	}

	public void action() {

	}

	public void moveTo(Point2D.Double pos) {
		this.move.setLocation(pos);
		this.isMovingTo = true;
	}

	public void moveTo(int x, int y) {
		this.move.setLocation(x, y);
		this.isMovingTo = true;
	}

	public void setVelocity(Point2D.Double vel) {
		this.vel.setLocation(vel);
	}

	public void setVelocity(double velx, double vely) {
		this.vel.setLocation(velx, vely);
	}

	public void setSquare(Square square) {
		this.square = square;
	}

	public Square getSquare() {
		return this.square;
	}

	public void addVelocity(Point2D.Double vel) {
		this.vel.setLocation(this.vel.getX() + vel.getX(), this.vel.getY()
				+ vel.getX());
		this.isMoving = true;
	}

	public void addVelocity(double velx, double vely) {
		this.vel.setLocation(this.vel.getX() + velx, this.vel.getY() + vely);
		this.isMoving = true;
	}

	public void addPos(Point2D.Double pos) {
		this.pos.setLocation((int) (this.pos.getX() + pos.getX()),
				(int) (this.pos.getY() + pos.getY()));
	}

	public void addPos(double posx, double posy) {
		this.pos.setLocation((int) Math.round((this.pos.getX() + posx)),
				(int) Math.round((this.pos.getY() + posy)));
	}

	public void setSize(double size) {
		if (size > Unit.MAX_SIZE)
			size = Unit.MAX_SIZE;
		if (size < Unit.MIN_SIZE)
			size = Unit.MIN_SIZE;
		this.size = size;
	}

	public void setSizeSmooth(double size, double resizespeed) {
		this.newsize = size;
		this.resizespeed = resizespeed;
		this.resize = true;
	}

	public void setSizeSmooth(double size) {
		setSizeSmooth(size, 40);
	}

	public double getSize() {
		return this.size;
	}

	public double getRadius() {
		return this.size / 2;
	}

	public void setColor(Color color) {
		this.color = color;
	}

	public Color getColor() {
		return this.color;
	}

	public Point2D.Double getPosition() {
		return this.pos;
	}

	public Point2D.Double getVelocity() {
		return this.vel;
	}

	public boolean isMoving() {
		return this.isMoving;
	}

	public void setMother(boolean mother) {
		this.isMother = mother;
	}

	public boolean isMother() {
		return this.isMother;
	}

	public void setControlable(boolean setControlable) {
		this.isControlable = setControlable;
	}

	public boolean isControlable() {
		return this.isControlable;
	}

	public void setSelected(boolean isSelected) {
		this.isSelected = isSelected;
	}

	public boolean isSelected() {
		return this.isSelected;
	}

	public Player getPlayer() {
		return this.player;
	}
}
